﻿# CoffeeScript
if not window.Moshu
    window.Moshu = new Object();
    
class window.Moshu.Logger
    constructor : ()->
    
    @redirectOutput : (domElement) ->
        Moshu.Logger.domElement  = domElement
    log : (msg) ->
        if not Moshu.Logger.domElement
            console.log(msg)
        else
            Moshu.Logger.domElement.innerHTML += "<span style='color:green'>"+msg+"</span><br>"
    logError : (msg) ->
        if not Moshu.Logger.domElement
            console.log(msg)        
        else
            Moshu.Logger.domElement.innerHTML += "<span style='color:red'>"+msg+"</span><br>"
    
# Observable class - used to allow custom event binding
# used to be inherited by others
class window.Moshu.Observable extends Moshu.Logger
    constructor:()->
        @events = []    
    bind : (type, fnc) ->
        if !@events
            @events = []
        if not @events[type]
            @events[type] = []        
        @events[type].push(fnc);
    unbind : (type, fnc) ->        
        if @events
            if @events[type]
                for ev,i in @events[type]
                    if ev is fnc
                        @events[type].splice(i,1);                
    notify : (type, args)->        
        if @events 
            x = true
            if @events[type] and @events[type].length
                for fnc in @events[type]
                    x = x && fnc(args)                                
            x

window.requestAnimFrame = 
    window.requestAnimationFrame ||	window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||window.msRequestAnimationFrame ||(callback,element) -> window.setTimeout(callback, 1000 / 60)
    
window.startAnimation = (animationStep)->
    self = this
    window.requestAnimFrame(animationStep)

window.Moshu.AnimationManager = 
    stopped : true
    interval: null
    observers: []    
    bind: (obj,fnc) ->        
        if typeof fnc is "function"
            @observers.push({
                obj: obj,
                fnc : fnc
            });
            @start()
    unbind: (fnc) ->
        for obs,i in @observers
            if obs.fnc is fnc
                @observers.splice(i,1)
        if !@observers or @observers.length is 0
            @stop()
        @observers
    lastTime: null
    onAnimationFrame: (time) ->                        
        self = window.Moshu.AnimationManager       
        if not self.stopped            
            if self.lastTime and self.observers and self.observers.length>0
                dt = time - self.lastTime
                for obs,i in self.observers                    
                    obs.fnc.call(obs.obj,dt)
                    
            self.lastTime = time
        if not self.stopped        
            self.interval = window.startAnimation(self.onAnimationFrame)
    start : () ->        
        if @stopped
            @interval = window.startAnimation(@onAnimationFrame)
            @stopped = false
    stop : () ->
        @stopped = true 
        @lastTime = null
        

class window.Moshu.Test    
    constructor : (@name, @fnc) ->        
    test : () ->
        @failed = false
        @fnc()
        @failed
    
class window.Moshu.Tests extends Moshu.Logger
    constructor : (@name) ->
        @arr = []
        @logger = console.log
    add : (name, fnc) ->
        test = new Moshu.Test(name,fnc)
        @arr.push(test)
    test : (test, condition) ->
        @log("Testing...")
        for @currentTest in @arr  
            @log("Testing "+@currentTest.name)      
            if !@currentTest.test()
                @log(@currentTest.name + " passed.")
            else                
                @logError(@currentTest.name + " failed.")
            @log("")      
    assert : (name, condition) ->
        if condition
            @log(name + " passed.")            
        else
            @currentTest.failed = true
            @logError(name + " failed.")
            #console.log (name + " failed.")